home *** CD-ROM | disk | FTP | other *** search
/ The Original Shareware 1.1 / The Original Shareware (WeMake CDs)(Volume 1.1)(CDs, Inc)(1993).iso / 23 / lazer12.zip / LAZER.C < prev    next >
C/C++ Source or Header  |  1988-10-31  |  13KB  |  762 lines

  1. /********************************************************************
  2.  * LAZER.C   Version 1.2        Copyright (c) 1987 Jim Bumgardner
  3.  *
  4.  * Text Formatter
  5.  * 
  6.  * for OKIDATA LASERLINE (HP Compatable) Laser Printer
  7.  *
  8.  * LAZER has been compiled in Manx (Aztec) C, Turbo C and VAX C.
  9.  *
  10.  ********************************************************************/
  11.  
  12. #include <stdio.h>
  13. #include <ctype.h>
  14. #include <math.h>
  15.  
  16. FILE *ifile,*ofile;
  17.  
  18. int lineno,pageno,copies;
  19. char author[] = "(c) James Bumgardner 1987";
  20. char *invcmd = "Invalid Command";
  21. char *invarg = "Invalid Argument";
  22. char *misarg = "Missing Argument";
  23. char *premeof = "Premature End of File";
  24.  
  25. char *strchr(),*get_filename();
  26. void *malloc();
  27.  
  28. int grey = 25,pattern = 1,port = 0;
  29. char outfile = 0,ignore_cr = 0;
  30. char nodownload;
  31.  
  32. #define pputc(c,p)    biosprint(0,c,p)
  33. #define init_printer(p)    biosprint(1,0,p)
  34.  
  35. unsigned char cmdflag;
  36.  
  37. main(argc,argv)
  38. char *argv[];
  39. {
  40.     int c;
  41.  
  42.  
  43.     parse_cmd(argc,argv);
  44.  
  45.     cmdflag = 0;
  46.     while (1)
  47.     {
  48.         c = getc2();
  49.         if (c == EOF) {
  50.             if (close_file())
  51.                 break;
  52.             else {
  53.                 cmdflag = 1;
  54.                 continue;
  55.             }
  56.         }
  57.         if (cmdflag)
  58.         {
  59.             switch (c)    {
  60.             case '[':    outchar('[');        /* no break */
  61.             case ']':    cmdflag = 0;    break;
  62.             case ';':    skip_comment();        break;
  63.             case '\n':    break;
  64.             case 'F':    get_font();        break;
  65.             case 'M':    get_margins();        break;
  66.             case 'I':    if (include_file())    cmdflag = 0;
  67.                     break;
  68.             case 'T':
  69.             case 'P':
  70.             case 'p':
  71.             case 'G':
  72.             case 'H':
  73.             case 'V':
  74.             case 'D':
  75.             case 'B':
  76.             case 'A':
  77.             case 'O':
  78.                     get_nval(c);        break;
  79.             case '/':
  80.             case '!':
  81.             case '_':    toggle_effect(c);    break;
  82.             case 'f':    if (copies > 1)
  83.                         pprintf("\033&l%dX",copies);
  84.                     outchar(12);        break;
  85.             case '(':    symbol_set();        break;
  86.             case 'L':    locate_cursor();    break;
  87.             case 'R':    print_rule();        break;
  88.             case 'E':    outchar(27);        break;
  89.             case '*':    macro_handler();    break;
  90.             case '^':    get_cntrl();        break;
  91.             case 'N':    toggle_flag(&ignore_cr); break;
  92.             }
  93.         }
  94.         else    {
  95.             if (c == '[')
  96.                 cmdflag = 1;
  97.             else {
  98.                 if (c == '\n') {
  99.                     if (ignore_cr)    continue;
  100.                     outchar('\r');
  101.                 }
  102.                 outchar(c);
  103.             }
  104.         }
  105.     }
  106.     if (copies > 1)
  107.         pprintf("\033&l%dX",copies);
  108.     outstr("\033E");
  109. }
  110.  
  111. parse_cmd(argc,argv)
  112. char *argv[];
  113. {
  114.     char *ifname,*ofname;
  115.     int i,synflg;
  116.     synflg = 0;
  117.     ifname = ofname = NULL;
  118.     for (i = 1; i < argc; ++i) {
  119.         if (argv[i][0] == '-') {
  120.             switch(toupper(argv[i][1])) {
  121.             case 'N':    nodownload = 1;
  122.                     break;
  123.             case 'C':    copies = atoi(&argv[i][2]);
  124.                     break;
  125.             default:    synflg = 1;    break;
  126.             }
  127.         }
  128.         else {
  129.             if (ifname)    ofname = argv[i];
  130.             else        ifname = argv[i];
  131.         }
  132.     }
  133.     if (ifname == 0 || synflg)
  134.     {
  135.         fputs(
  136.             "Syntax:\n\tLAZER [options] file [port# or file]\n"
  137.             "\nOptions:\n"
  138.             "\t-N\tDon't Download Fonts\n"
  139.             "\t-C#\tCopies\n"
  140.             "\nExamples:\n"
  141.             "\tLAZER TEST.TXT 2\n"
  142.             "\tLAZER -C3 TEST.TXT TEXT.OUT\n",stderr);
  143.         exit();
  144.     }
  145.     if (ofname) {
  146.         str_toupper(ofname);
  147.         if (strcmp(ofname,"2") == 0 ||
  148.             strcmp(ofname,"LPT2") == 0 ||
  149.             strcmp(ofname,"LPT2:") == 0)
  150.             port = 1;
  151.         else     if (strcmp(ofname,"1") &&
  152.                 strcmp(ofname,"LPT1") &&
  153.                 strcmp(ofname,"LPT1:"))
  154.         {
  155.             outfile = 1;
  156.             if ((ofile = fopen(ofname,"wb")) == 0)
  157.             {
  158.                 fprintf(stderr,"Can't open %s for output\n",ofname);
  159.                 exit();
  160.             }
  161.         }
  162.     }
  163.     if (ofile == 0)        init_printer(port);
  164.     open_file(ifname,".TXT");
  165. }
  166.  
  167.  
  168. str_toupper(str)
  169. char *str;
  170. {
  171.     while (*str)    *str++ = toupper(*str);
  172. }
  173.  
  174. skip_comment()
  175. {
  176.     register int c;
  177.     do    {
  178.         c = getc2();
  179.     } while (c != '\n' && c != EOF);
  180. }
  181.  
  182. get_number()
  183. {
  184.     register int c;
  185.     char pts[8],*p;
  186.  
  187.     p = pts;
  188.     c = getc2();
  189.     while (isdigit(c) || c == '.' || c == '-')
  190.     {
  191.         *p++ = c;
  192.         c = getc2();
  193.     }
  194.     ungetc2(c);
  195.     *p = 0;
  196.     return(atoi(pts));
  197. }
  198.  
  199. char efstr[] = "!/_";
  200. char *efcmd[3][2] = 
  201. {"\033(s0B","\033(s3B",    /* Bold */
  202.  "\033(s0S","\033(s1S",    /* Italic */
  203.  "\033&d@","\033&dD"};    /* Underlining */
  204.  
  205. char eftog[3];
  206.  
  207. toggle_effect(c)
  208. int c;
  209. {
  210.     char *p;
  211.     int effect;
  212.     c = toupper(c);
  213.     p = strchr(efstr,c);    /* Already been checked */
  214.     effect = (int) p - (int) efstr;
  215.     eftog[effect] ^= 1;
  216.     outstr(efcmd[effect][eftog[effect]]);
  217.  
  218.     if (effect == 1 && eftog[effect] == 0 && eftog[0])
  219.         outstr(efcmd[0][1]);
  220.     if (effect == 0 && eftog[effect] == 0 && eftog[1])
  221.         outstr(efcmd[1][1]);
  222. }
  223.  
  224. get_font()
  225. {
  226.     int fno;
  227.     if (is_number())
  228.     {
  229.         fno = get_number();
  230.         if (next_char() == '<')    download_font(fno);
  231.         pprintf("\033(%dX",fno);
  232.     }
  233.     else
  234.         print_err(invarg);
  235. }
  236.  
  237. download_font(fno)
  238. {
  239.     char *p;
  240.     int c;
  241.     p = get_filename();
  242.     if (p && nodownload == 0) {
  243.         pprintf("\033*c%dD",fno);
  244.         open_file(p,".SFP");
  245.         fprintf(stderr,"<%s\n",p);
  246.         while ((c = getc(ifile)) != EOF)
  247.             outchar(c);
  248.         close_file();
  249.         pprintf("\033*c%dd5F",fno);
  250.     }
  251. }
  252.  
  253. get_cntrl()
  254. {
  255.     int c;
  256.     c = getc2();
  257.     c = toupper(c);
  258.     outchar(c - '@');
  259. }
  260.  
  261. symbol_set()
  262. {
  263.     int c;
  264.     outchar(27);    outchar('(');
  265.     c = getc2();    outchar(c);
  266.     c = getc2();    outchar(c);
  267. }
  268.  
  269. char marstr[] = {"LRTC"};
  270. char *marcmd[] = 
  271. {"\033&a%dL",
  272.  "\033&a%dM",
  273.  "\033&l%dE"};
  274.  
  275. get_margins()
  276. {
  277.     char *p;
  278.     int c,mar,val;
  279.  
  280.     c = getc2();
  281.     c = toupper(c);
  282.     if ((p = strchr(marstr,c)) == NULL)
  283.     {
  284.         print_err(invarg);
  285.         return;
  286.     }
  287.     mar = (int) p - (int) marstr;
  288.     if (mar == 3) {
  289.         outstr("\0339");
  290.         return;
  291.     }
  292.     else {
  293.         if (is_number() == 0)
  294.         {
  295.             print_err(misarg);
  296.             return;
  297.         }
  298.         val = get_number();
  299.         pprintf(marcmd[mar],val);
  300.     }
  301. }
  302.  
  303. get_nval(c)
  304. {
  305.     int val;
  306.     if (is_number() == 0)
  307.         return(print_err(misarg));
  308.     val = get_number();
  309.     switch(c) {
  310.     case 'T':
  311.     case 'V':
  312.     case 'H':
  313.     case 'B':
  314.     case 'P':    pprintf("\033(s%d%c",val,c);    break;
  315.     case 'O':
  316.     case 'D':    pprintf("\033&l%d%c",val,c);    break;
  317.     case 'A':    pprintf("\033*c%dd6F",val);    break;
  318.     case 'p':    pattern = val;            break;
  319.     case 'G':    grey = val;            break;
  320.     default:    print_err(invcmd);        break;
  321.     }
  322. }
  323.  
  324. char *signstr[] = {"-","","+"};
  325.  
  326. locate_cursor()
  327. {
  328.     int h,v;
  329.     int c,i,hs,vs;
  330.     i = next_char();
  331.     hs = vs = 0;
  332.     if (i == ',' || i == '+' || i == '-' || isdigit(i))
  333.     {
  334.         if (i == '+' || i == '-') {
  335.             if (i == '+')    hs = 1;
  336.             else        hs = -1;
  337.             getc2();
  338.             i = next_char();
  339.         }    
  340.         if (isdigit(i)) {
  341.             h = get_number();
  342.             i = next_char();
  343.         }
  344.         else     h = -1;
  345.         if (i == ',')
  346.         {
  347.             getc2();
  348.             i = next_char();
  349.             if (i == '+' || i == '-') {
  350.                 if (i == '+')    vs = 1;
  351.                 else        vs = -1;
  352.                 getc2();
  353.             }    
  354.             v = get_number();            
  355.         }
  356.         else    v = -1;
  357.         if (h >= 0)    pprintf("\033&a%s%dH",signstr[hs+1],h);
  358.         if (v >= 0)    pprintf("\033&a%s%dV",signstr[vs+1],v);
  359.     }
  360.     else    {
  361.         c = getc2();
  362.         switch (c) {
  363.         case 'S':    outstr("\033&f0S"); break;
  364.         case 'R':    outstr("\033&f1S"); break;
  365.         default:    return(print_err(invcmd));
  366.         }
  367.     }
  368. }
  369.  
  370. macro_handler()
  371. {
  372.     int val;
  373.     int c;
  374.     c = next_char();
  375.     if (isdigit(c))
  376.     {
  377.         val = get_number();
  378.         pprintf("\033&f%dy2X",val);
  379.     }
  380.     else    {
  381.         getc2();
  382.         switch (c) {
  383.         case '{':    val = get_number();
  384.                 pprintf("\033&f%dy0X",val);
  385.                 break;
  386.         case '}':    outstr("\033&f1X");
  387.                 break;
  388.         default:    print_err(invcmd);
  389.         }
  390.     }
  391. }
  392.  
  393. print_rule()
  394. {
  395.     int h,v;
  396.     int c;
  397.     
  398.     c = getc2();
  399.     h = get_number();
  400.     getc2();
  401.     v = get_number();
  402.     switch(toupper(c))    {
  403.     case 'S':
  404.     case 'B':    pprintf("\033*c%dh%dv0P",h,v); break;
  405.     case 'G':    pprintf("\033*c%dg%dh%dv2P",grey,h,v); break;
  406.     case 'P':    pprintf("\033*c%dg%dh%dv3P",pattern,h,v); break;
  407.     }
  408. }
  409.  
  410. toggle_flag(f)
  411. char *f;
  412. {
  413.     int c;
  414.     c = getc2();
  415.     switch (toupper(c)) {
  416.     case '+':
  417.     case 'Y':    *f = 1;    break;
  418.     case '-':
  419.     case 'N':    *f = 0;    break;
  420.     default:    *f ^= 1;    
  421.             ungetc2(c);
  422.             break;
  423.     }
  424. }
  425.  
  426. char *get_filename()
  427. {
  428.     static char fname[81];
  429.     char *p;
  430.     int c;
  431.     
  432.     c = getc2();
  433.     if (c != '<') {
  434.         print_err(invcmd);
  435.         return(NULL);
  436.     }
  437.     p = fname;
  438.     while (1) {
  439.         c = getc2();
  440.         if (c == '>' || c == EOF)
  441.             break;
  442.         *p++ = c;
  443.     }
  444.     if (c == EOF)    {
  445.         print_err(premeof);
  446.         return(NULL);
  447.     }
  448.     *p = '\0';
  449.     return(fname);
  450. }
  451.  
  452. include_file()
  453. {
  454.     char *p;
  455.     int c;
  456.     c = next_char();
  457.     if (toupper(c) == 'B')
  458.         get_bmap();
  459.     else if (toupper(c) == 'P')
  460.         get_pcx();
  461.     else if (toupper(c) == 'R')
  462.         get_raw();
  463.     else {
  464.         p = get_filename();    
  465.         if (p) {
  466.             open_file(p,".TXT");
  467.             return(1);
  468.         }
  469.     }
  470.     return(0);
  471. }
  472.  
  473. get_raw()
  474. {
  475.     char *p;
  476.     int c;
  477.     getc2();
  478.     p = get_filename();
  479.     if (p) {
  480.         open_file(p,".PRN");
  481.         fprintf(stderr,"<%s(R)\n",p);
  482.         while ((c = getc(ifile)) != EOF)
  483.             outchar(c);
  484.         close_file();
  485.     }
  486. }
  487.  
  488. get_bmap()
  489. {
  490.     int reso,ydim,xdim;
  491.     int y,c,invert;
  492.     char *buf,*p,bl;
  493.     reso = 300;
  494.     getc2();
  495.     c = next_char();
  496.     if (toupper(c) == 'I')    {
  497.         invert = 1;
  498.         getc2();
  499.     }
  500.     else    invert = 0;
  501.  
  502.     if (is_number())
  503.         reso = get_number();
  504.     p = get_filename();
  505.     if (p) {
  506.         open_file(p,".MAP");
  507.         xdim = getw(ifile);
  508.         ydim = getw(ifile);
  509.         fprintf(stderr,"%s: %d X %d\n",p,xdim,ydim);
  510.         xdim >>= 3;
  511.         buf = malloc(xdim+16);
  512.         sprintf(buf,"\033*b%dW",xdim);
  513.         bl = strlen(buf);
  514.         pprintf("\033*t%dR\033*r1A",reso);
  515.         y = 0;
  516.         while (y++ < ydim && fread(buf+bl,xdim,1,ifile)) 
  517.         {
  518.             if (invert)    invert_bmap(buf+bl,xdim);
  519.             outbuf(buf,xdim+bl);
  520.             if ((y & 63) == 0)
  521.                 fprintf(stderr,"\r%d/%d",y - 1,ydim);
  522.         }
  523.         fprintf(stderr,"\n");
  524.         outstr("\033*rB");
  525.         close_file();
  526.         free(buf);
  527.     }
  528. }
  529.  
  530. get_pcx()
  531. {
  532.     int reso,ydim,xdim;
  533.     int y,x,c,n,invert;
  534.     char *buf,*bufptr,*p,bl;
  535.     int pcx_hed[64];
  536.     reso = 300;
  537.  
  538.     getc2();
  539.     c = next_char();
  540.     if (toupper(c) == 'I')    {
  541.         invert = 1;
  542.         getc2();
  543.     }
  544.     else    invert = 0;
  545.     if (is_number())
  546.         reso = get_number();
  547.     p = get_filename();
  548.     if (p == NULL)    return;
  549.     open_file(p,".PCX");
  550.     fread(pcx_hed,0x80,1,ifile);
  551.     xdim = pcx_hed[4]+1;
  552.     ydim = pcx_hed[5]+1;
  553.     fprintf(stderr,"%s: %d X %d\n",p,xdim,ydim);
  554.     xdim = pcx_hed[33];
  555.     buf = malloc(xdim+16);
  556.     sprintf(buf,"\033*b%dW",xdim);
  557.     bl = strlen(buf);
  558.     bufptr = buf+bl;
  559.     pprintf("\033*t%dR\033*r1A",reso);
  560.     for (y = 0; y < ydim; ++y)
  561.     {
  562.         x = 0;
  563.         while (x < xdim) {
  564.             if ((c = getc(ifile)) == EOF)
  565.             {
  566.                 fprintf(stderr,"\nPremature EOF\n");
  567.                 break;
  568.             }
  569.             if ((c & 0xC0) != 0xC0)
  570.                 bufptr[x++] = c;
  571.             else {
  572.                 n = c & 0x3F;
  573.                 c = getc(ifile);
  574.                 while (n--)
  575.                     bufptr[x++] = c;
  576.             }
  577.         }
  578.         if (c == EOF)    break;
  579.         if (invert)    invert_bmap(bufptr,xdim);
  580.         outbuf(buf,xdim+bl);
  581.         if ((y & 63) == 0)
  582.             fprintf(stderr,"\r%d/%d",y,ydim);
  583.     }
  584.     fprintf(stderr,"\n");
  585.     outstr("\033*rB");
  586.     close_file();
  587.     free(buf);
  588. }
  589.  
  590. invert_bmap(str,n)
  591. unsigned char *str;
  592. {
  593.     while (n--)
  594.     {
  595.         *str++ = ~*str;
  596.     }
  597. }
  598.  
  599. /************************************
  600.  * File Handling
  601.  *
  602.  ************************************/
  603.  
  604. FILE *save_file[16];
  605. int filecount;
  606. int linecount[16];
  607. char *sfname[16];
  608.  
  609. open_file(fname,ext)
  610. char *fname,*ext;
  611. {
  612.     if (filecount == 16)
  613.         return(print_err("Too Much Include Nesting"));
  614.     linecount[filecount] = lineno;
  615.     lineno = linecount[filecount] = 0;
  616.     sfname[filecount] = malloc(strlen(fname) + 5);
  617.     strcpy(sfname[filecount],fname);
  618.     if (strchr(fname,'.') == NULL)    strcat(sfname[filecount],ext);
  619.     
  620.     if ((ifile = fopen(sfname[filecount],"rb")) == NULL)
  621.     {
  622.         fprintf(stderr,"Can't open %s",sfname[filecount]);
  623.         exit();
  624.     }
  625.     save_file[filecount] = ifile;
  626.     ++filecount;
  627. }
  628.  
  629. close_file()
  630. {
  631.     fclose(ifile);
  632.     --filecount;
  633.     free(sfname[filecount]);
  634.     if (filecount)
  635.     {
  636.         lineno = linecount[filecount-1];
  637.         ifile = save_file[filecount-1];
  638.         return(0);
  639.     }
  640.     else    return(1);
  641. }
  642.  
  643. /*****************
  644.  * Look Ahead
  645.  *****************/
  646.  
  647. next_char()
  648. {
  649.     register int c;
  650.     c = getc2();
  651.     ungetc2(c);
  652.     return(c);
  653. }
  654.  
  655. is_number()
  656. {
  657.     register int c;
  658.     c = next_char();
  659.     return(isdigit(c));
  660. }
  661.  
  662. /********************
  663.  * Character I/O
  664.  ********************/
  665.  
  666. char unget;
  667. savebuf[257];
  668.  
  669. ungetc2(c)    /* Supports 256 ungets (First in, Last Out) */
  670. {
  671.     savebuf[unget++] = c;
  672. }
  673.  
  674. getc2()
  675. {
  676.     register int c;
  677.     if (unget)    c = savebuf[--unget];
  678.     else        c = getc(ifile);
  679.     if (c == 26)    return(EOF);
  680.     if (c == '\r')    {
  681.         c = getc(ifile);
  682.         if (c != '\n') {
  683.             ungetc(c,ifile);
  684.             return('\r');
  685.         }
  686.         else    ++lineno;
  687.     }
  688.     
  689.     return(c);
  690. }
  691.  
  692. /***********************
  693.  * Error Handling
  694.  ***********************/
  695.  
  696. print_err(str)
  697. char *str;
  698. {
  699.     if (filecount > 1)
  700.         fprintf(stderr,"File %s - Line %d: %s\n",
  701.             sfname[filecount-1],lineno+1,str);
  702.     else
  703.         fprintf(stderr,"Line %d: %s\n",
  704.             lineno+1,str);
  705.     return(0);
  706. }
  707.  
  708. /**********************
  709.  * Printer Output
  710.  **********************/
  711.  
  712. outbuf(buf,len)
  713. char *buf;
  714. {
  715.     if (outfile)
  716.         fwrite(buf,len,1,ofile);
  717.     else
  718.         while (len--)
  719.             pputc(*buf++,port);
  720. }
  721.  
  722. pprintf(tmp,a1,a2,a3)
  723. char *tmp;
  724. {
  725.     char obuf[81];
  726.     sprintf(obuf,tmp,a1,a2,a3);
  727.     outstr(obuf);
  728. }
  729.  
  730. outstr(buf)
  731. char *buf;
  732. {
  733.     if (outfile)
  734.         while (*buf)
  735.             putc(*buf++,ofile);
  736.     else
  737.         while (*buf)
  738.             pputc(*buf++,port);
  739. }
  740.  
  741. outchar(c)
  742. {
  743.     static int tx;
  744.     static char tabs[] = "        ";
  745.  
  746.     if (cmdflag == 0) {    /* Deal with Tabs Correctly */
  747.         switch (c) {
  748.         case '\r':
  749.         case '\n':    tx = 0;    break;
  750.         case '\t':    outbuf(tabs,8 - tx%8);
  751.                 tx += 8-tx%8;
  752.                 return;
  753.         case '\b':    --tx;    break;
  754.         default:    ++tx;    break;
  755.         }
  756.     }
  757.     if (outfile)
  758.         putc(c,ofile);
  759.     else
  760.         pputc(c,port);
  761. }
  762.